package edu.nf.vac.auth.util;

import cn.hutool.core.date.DateUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;

import java.security.Key;
import java.util.Date;
import java.util.Map;
import java.util.UUID;

/**
 * @Author : QYM
 * @create 2022/3/30
 */
@Slf4j
public class JwtUtils {
    /**
     * 密钥，用于signature（签名）部分解密
     */
    private static final Key KEY = Keys.secretKeyFor(SignatureAlgorithm.HS512);
    /**
     * 签发者
     */
    private static final String ISS = "edu.nf";

    /**
     * 生成token
     * @param claims
     * @param ttl
     * @return
     */
    public static String createToken(Map<String, Object> claims, long ttl) {
        JwtBuilder builder = Jwts.builder()
                //获取签名秘钥，并采用HS512算法对JWT进行的签名
                .signWith(KEY)
                //jwt唯一标识
                .setId(UUID.randomUUID().toString())
                //设置需要签署的内容
                .setClaims(claims)
                //设置发证人
                .setIssuer(ISS)
                //主题
                .setSubject("JWT_AUTH")
                //签名时间
                .setIssuedAt(new Date());
        //过期时间
        if(ttl >= 0){
            builder.setExpiration(getExpDate(ttl));
        }
        return builder.compact();
    }

    /**
     * 创建token过期时间
     * @param ttl
     * @return
     */
    private static Date getExpDate(long ttl){
        Date expDate = DateUtil.date(System.currentTimeMillis() + ttl);
        log.info("Token过期时间：" + DateUtil.format(expDate, "yyyy-MM-dd hh:mm:ss"));
        return expDate;
    }

    /**
     * 获取载体内容
     * @param token
     * @param type
     * @param <T>
     * @return
     */
    public static <T> T getPayload(String token, String name, Class<T> type) {
        Claims claims = Jwts.parserBuilder()
                .setSigningKey(KEY)
                .build()
                .parseClaimsJws(token)
                .getBody();
        return claims.get(name, type);
    }

    /**
     * 验证Token是否正确
     */
    public static void verify(String token){
        //通过密钥验证Token
        Jwts.parserBuilder()
                .setSigningKey(KEY)
                .build()
                .parseClaimsJws(token);
    }
}
